package org.jeecg.modules.doctor;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.annotation.Resource;
import javax.persistence.RollbackException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.modules.dic.entity.DicBeGoodAt;
import org.jeecg.common.modules.dic.service.IDicBeGoodAtService;
import org.jeecg.common.modules.doctor.entity.Doctor;
import org.jeecg.common.modules.doctor.entity.DoctorRegisterHospital;
import org.jeecg.common.modules.doctor.entity.DoctorRegisterRecord;
import org.jeecg.common.modules.doctor.service.*;
import org.jeecg.common.modules.doctor.vo.AssistantInfoReqVo;
import org.jeecg.common.modules.doctor.vo.DoctorRegisterVo;
import org.jeecg.common.modules.doctor.vo.DoctorReqVo;
import org.jeecg.common.modules.makeAppointment.entity.MakeAppointment;
import org.jeecg.common.modules.register.entity.RegisterPatient;
import org.jeecg.common.modules.register.entity.RegisterPayOrder;
import org.jeecg.common.modules.register.service.IRegisterPatientService;
import org.jeecg.common.modules.register.service.IRegisterPayOrderService;
import org.jeecg.common.modules.registerRefoundAudit.entity.RegisterRefoundAudit;
import org.jeecg.common.modules.registerRefoundAudit.service.IRegisterRefoundAuditService;
import org.jeecg.common.modules.wx.entity.WxUserinfo;
import org.jeecg.common.modules.wx.service.IWxUserinfoService;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.enums.RegisterEnum;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.modules.doctor.entity.DoctorRegister;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.data.response.DoctorRegisterAddRes;
import org.jeecg.modules.data.service.PageReturn;
import org.jeecg.modules.data.service.RegisterService;
import org.jeecg.modules.system.vo.ResultVo;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;

/**
 * @Description: doctor_register
 * @Author: jeecg-boot
 * @Date: 2020-12-18
 * @Version: V1.0
 */
@Api(tags = "doctor_register")
@RestController
@RequestMapping("/doctorRegister/doctorRegister")
@Slf4j
public class DoctorRegisterController extends JeecgController<DoctorRegister, IDoctorRegisterService> {
    @Autowired
    private IDoctorService doctorService;
    @Autowired
    private IDoctorRegisterService doctorRegisterService;
    @Autowired
    private IDoctorRegisterHospitalService doctorRegisterHospitalService;
    @Autowired
    private IDicBeGoodAtService dicBeGoodAtService;
    @Autowired
    private IDoctorRegisterRecordService doctorRegisterRecordService;

    @Resource
    private IDoctorConfigService doctorConfigService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private IRegisterPayOrderService registerPayOrderService;
    @Resource
    private IWxUserinfoService wxUserinfoService;
    @Autowired
    private IRegisterRefoundAuditService registerRefoundAuditService;
    @Autowired
    private IRegisterPatientService registerPatientService;

    /**
     * 分页列表查询
     *
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "doctor_register-分页列表查询")
    @ApiOperation(value = "doctor_register-分页列表查询", notes = "doctor_register-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {

        //分页数据开始的记录数
        int dataStart = (pageNo - 1) * pageSize;

        String doctorName = req.getParameter("doctorName");
        String hospitalId = req.getParameter("hospitalId");
        String departmentId = req.getParameter("departmentId");
        String visitTime = req.getParameter("visitTime");

        //（1）先查询所有信息
        List<DoctorRegisterVo> doctorReqVos = doctorRegisterService.getInfoList(doctorName, hospitalId, departmentId, visitTime, dataStart, pageSize);

        //（2）获取总条数
        Integer count = doctorRegisterService.getDoctorRegisterCount(doctorName, hospitalId, departmentId, visitTime);

        //（3）组织分页的返回数据
        PageReturn pageReturn = new PageReturn();
        ResultVo vo = pageReturn.initResultVo(doctorReqVos, count, pageNo, pageSize);
        return Result.ok(vo);
    }

    /**
     * 搜索医生
     */
    @GetMapping(value = "/searchDoctor")
    public Result<?> searchDoctor(String name) {
        List<AssistantInfoReqVo> doctors = doctorService.searchRegisterDoctor(name);
        return Result.ok(doctors);
    }

    /**
     * 检查该医生是否已设置挂号分成比例
     */
    @GetMapping(value = "/registerRatioCheck")
    public Result<?> registerRatioCheck(String doctorId) {
        Doctor doctor = doctorConfigService.registerRatioCheck(doctorId);
        return Result.ok(doctor);
    }

    /**
     * 列表所需的号源医院列表、号源科室列表
     */
    @GetMapping(value = "/signal")
    public Result<?> signal() {
        //【一】查询所有的号源医院
        List<DoctorRegisterHospital> doctorRegisterHospitals = doctorRegisterHospitalService.getAll();

        //【二】获取所有的挂号科室
        List<DicBeGoodAt> dicBeGoodAts = doctorRegisterHospitalService.getRegisterDepartment();
        Map resource = new HashMap();
        resource.put("hospital", doctorRegisterHospitals);
        resource.put("department", dicBeGoodAts);
        return Result.ok(resource);
    }

    /**
     * 添加：展示
     *
     * @return
     */
    @AutoLog(value = "doctor_register-添加")
    @ApiOperation(value = "doctor_register-添加", notes = "doctor_register-添加")
    @GetMapping(value = "/add")
    public Result<?> add(String doctorId) {

        DoctorRegisterAddRes doctorRegisterAddRes = new DoctorRegisterAddRes();
        //获取所有的挂号医院信息
        doctorRegisterAddRes.setHospitals(doctorRegisterHospitalService.getAll());
        if (doctorId != null) {
            Doctor doctor = doctorService.getById(doctorId);
            doctorRegisterAddRes.setDoctor(doctor);
        }
        return Result.ok(doctorRegisterAddRes);
    }

    /**
     * 添加保存
     *
     * @param doctorRegisters
     * @return
     */
    @AutoLog(value = "doctor_register-添加")
    @ApiOperation(value = "doctor_register-添加", notes = "doctor_register-添加")
    @PostMapping(value = "/add")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> add(@RequestBody List<DoctorRegister> doctorRegisters) {
        //暂时设置时间 临时
//		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
//		Date startTime1 = null;
//		Date endTime1 = null;
//		try {
//			startTime1 = sdf.parse("08:00");
//			endTime1 = sdf.parse("09:00");
//		} catch (ParseException e) {
//			e.printStackTrace();
//		}
        for (DoctorRegister doctorRegister : doctorRegisters) {
            //计算分钟数
            long startTime = doctorRegister.getStartTime().getTime();
            long endTime = doctorRegister.getEndTime().getTime();
            // 临时
//			long startTime = startTime1.getTime();
//			long endTime = endTime1.getTime();
            long min = (endTime - startTime);
            //生成对应的出诊时间段
            int minSplite = (int) min / doctorRegister.getCount();
            doctorRegister.setStartTime(doctorRegister.getStartTime());
            doctorRegister.setEndTime(doctorRegister.getEndTime());
//			doctorRegister.setStartTime(startTime1);
//			doctorRegister.setEndTime(endTime1);
//			LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//			doctorRegister.setCreateTime(new Date());
//			doctorRegister.setCreateUser(sysUser.getUsername());
            //检测某天的出诊片段
            DoctorRegister doctorRegisterCheck = this.checkPart(doctorRegister);
            if (Objects.isNull(doctorRegisterCheck)) {
                doctorRegister.setNumEnd(doctorRegister.getNumStart() + doctorRegister.getCount() - 1);  //计算结束序号
                boolean res = doctorRegisterService.save(doctorRegister);
                if (res) {
                    //添加挂号序号记录
                    for (int num = doctorRegister.getNumStart(); num <= doctorRegister.getNumEnd(); num++) {
                        DoctorRegisterRecord doctorRegisterRecord = new DoctorRegisterRecord();
                        doctorRegisterRecord.setDoctorRegisterId(doctorRegister.getId());
                        doctorRegisterRecord.setVisitNum(num);
                        doctorRegisterRecord.setStartTime(new Date(startTime));
                        doctorRegisterRecord.setEndTime(new Date(startTime + minSplite));
                        startTime = startTime + minSplite;
                        doctorRegisterRecordService.save(doctorRegisterRecord);
                    }
                } else {
                    return Result.error("保存失败！");
                }
            } else {
                throw new RuntimeException("该" + doctorRegister.getVisitTime() + "的出诊时间段已重复，请重新选择！");
               // throw new RuntimeException("该" + doctorRegister.getVisitTime() + "的出诊时间段已重复，请重新选择！");
            }
        }
        return Result.ok("保存成功！");
    }

    /**
     * 编辑
     *
     * @param doctorRegister
     * @return
     */
    @AutoLog(value = "doctor_register-编辑")
    @ApiOperation(value = "doctor_register-编辑", notes = "doctor_register-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody DoctorRegister doctorRegister) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        doctorRegister.setUpdateTime(new Date());
        doctorRegister.setUpdateUser(sysUser.getUsername());

        log.info("+++++++提交数据+++++++：\n{}", doctorRegister);
        //检测某天的出诊片段
        DoctorRegister doctorRegisterCheck = this.checkPart(doctorRegister);

        log.info("+++++++检查数据+++++++：\n{}", doctorRegisterCheck);
        if (doctorRegisterCheck.getId().equals(doctorRegister.getId())) {
            boolean res = doctorRegisterService.updateById(doctorRegister);
            if (res) {
                return Result.ok("保存成功！");
            } else {
                return Result.error("保存失败！");
            }
        } else {
            return Result.error("该出诊日期的出诊时间段已重复，请重新选择！");
        }
    }

    /**
     * 检测某天的上午、下午和晚上的挂号情况，且保整不重复
     */
    public DoctorRegister checkPart(DoctorRegister doctorRegister) {
        return doctorRegisterService.getDoctorRegisterByDoctorIdAndVisitTimePart(doctorRegister.getDoctorId(), doctorRegister.getVisitTime(), doctorRegister.getVisitPart());
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "doctor_register-通过id删除")
    @ApiOperation(value = "doctor_register-通过id删除", notes = "doctor_register-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) throws ParseException {
        //检测当前的挂号数据是否已经过期
        DoctorRegister doctorRegister = doctorRegisterService.getById(id);
        String visitTime = doctorRegister.getVisitTime();
        String visitPart = doctorRegister.getVisitPart();
        String part = "";
        if (visitPart.equals("上午")) {
            part = "12:00:00";
        } else if (visitPart.equals("下午")) {
            part = "18:00:00";
        } else if (visitPart.equals("晚上")) {
            part = "23:59:59";
        }
        Date date = RegisterService.StrToDate(visitTime + " " + part);
        log.info("挂号单的日期：{}", date);
        log.info("当前日期：{}", new Date());
        if (date.before(new Date())) {
            return Result.error("本次挂号时间已过期，不可被删除！");
        }
        //检测该挂号下是否有挂号记录
        List<DoctorRegisterRecord> doctorRegisterRecords = doctorRegisterRecordService.getRegisterRecordList(id);
        if (Objects.nonNull(doctorRegisterRecords) && doctorRegisterRecords.size() > 0) {
            return Result.error("本次挂号下已有患者进行挂号，不可被删除！");
        }
        // 删除挂号表信息
        boolean res = doctorRegisterService.removeById(id);
        // 删除挂号记录表提前创建的挂号信息
        List<DoctorRegisterRecord> doctorRegisterRecordsAll = doctorRegisterRecordService.getRegisterRecordListAll(id);
        for (DoctorRegisterRecord doctorRegisterRecord : doctorRegisterRecordsAll) {
            doctorRegisterRecordService.removeById(doctorRegisterRecord.getId());
        }
        if (res) {
            return Result.ok("删除成功！");
        } else {
            return Result.error("删除失败！");
        }
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "doctor_register-批量删除")
    @ApiOperation(value = "doctor_register-批量删除", notes = "doctor_register-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.doctorRegisterService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.ok("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "doctor_register-通过id查询")
    @ApiOperation(value = "doctor_register-通过id查询", notes = "doctor_register-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        DoctorRegister doctorRegister = doctorRegisterService.getById(id);
        if (doctorRegister == null) {
            return Result.error("未找到对应数据");
        }
        return Result.ok(doctorRegister);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param doctorRegister
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, DoctorRegister doctorRegister) {
        return super.exportXls(request, doctorRegister, DoctorRegister.class, "doctor_register");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, DoctorRegister.class);
    }


    /**
     * 停止挂号，已有挂号，运营申请退款
     *
     * @param id
     * @return
     */
    @AutoLog(value = "doctor_register-停止挂号，已有挂号，运营申请退款")
    @ApiOperation(value = "doctor_register-停止挂号，已有挂号，运营申请退款", notes = "doctor_register-停止挂号，已有挂号，运营申请退款")
    @GetMapping(value = "/updateRegisterStatus")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> updateRegisterStatus(@RequestParam String id, Integer invalid, HttpServletRequest req) {
        //伪删除挂号
        DoctorRegister doctorRegister = doctorRegisterService.getById(id);
        doctorRegister.setInvalid(invalid);
        doctorRegisterService.updateById(doctorRegister);
//        //获取所有挂号记录
//        List<DoctorRegisterRecord> doctorRegisterRecords = doctorRegisterRecordService.getDoctorRegisterRecord(id);
//        //退款
//        if (doctorRegisterRecords.size() > 0 && invalid == 1) {
//            for (DoctorRegisterRecord recods : doctorRegisterRecords) {
//
//
//                LambdaQueryWrapper<WxUserinfo> query = Wrappers.lambdaQuery();
//                query.eq(WxUserinfo::getOpenid, recods.getOpenid());
//                log.info(recods.getOpenid());
//                WxUserinfo wxUserinfo = wxUserinfoService.getOne(query); //获取微信用户
//                RegisterPayOrder payOrder = new RegisterPayOrder();
//                payOrder.setDoctorId(doctorRegister.getDoctorId());
//                payOrder.setRelationId(recods.getId());
//                payOrder.setStatus(RegisterEnum.OPERATE.getCode());
//                payOrder.setWxUserinfoId(wxUserinfo.getId());
//                RegisterPayOrder registerPayOrder = registerPayOrderService.getByRelationId(payOrder);
//
//                //生成退款申请记录
//                RegisterRefoundAudit registerRefoundAudit = new RegisterRefoundAudit();
//                registerRefoundAudit.setOpenid(recods.getOpenid());
//                registerRefoundAudit.setRegisterPayOrderId("0");
//                registerRefoundAudit.setStatus(0);
//                registerRefoundAudit.setDoctorId(doctorRegister.getDoctorId());
//                registerRefoundAudit.setRelationId(recods.getId());
//
//
//                //获取医生信息
//                Doctor doctorInfo = doctorService.getById(doctorRegister.getDoctorId());
//                registerRefoundAudit.setDoctorName(doctorInfo.getName());
//
//                //患者信息
//                registerRefoundAudit.setRequestTime(new Date());
//                registerRefoundAudit.setNickName(wxUserinfo.getNickname());
//
//
//                String patientId = doctorRegisterRecordService.getById(recods.getId()).getPatientId();
//                RegisterPatient patientInfo = registerPatientService.getById(patientId);
//                registerRefoundAudit.setMobile(patientInfo.getMobile());
//                registerRefoundAudit.setPatientName(patientInfo.getName());
//                registerRefoundAudit.setIdCard(patientInfo.getIdCard());
//                registerRefoundAuditService.save(registerRefoundAudit);
//            }
//        }

        return Result.ok(doctorRegister);
    }

    /**
     * 运营退款，同客服协商后，给患者退款
     *
     * @param id
     * @return
     */
    @AutoLog(value = "doctor_register-运营退款，同客服协商后，给患者退款")
    @ApiOperation(value = "doctor_register-运营退款，同客服协商后，给患者退款", notes = "doctor_register-运营退款，同客服协商后，给患者退款")
    @GetMapping(value = "/updateRegisterRefond")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> updateRegisterRefond(@RequestParam String id, Integer invalid, String doctorId, String xsResion, HttpServletRequest req) {
        //获取所有挂号记录
        DoctorRegisterRecord recods = doctorRegisterRecordService.getById(id);
        //退款
        LambdaQueryWrapper<WxUserinfo> query = Wrappers.lambdaQuery();
        query.eq(WxUserinfo::getOpenid, recods.getOpenid());
        log.info(recods.getOpenid());
        WxUserinfo wxUserinfo = wxUserinfoService.getOne(query); //获取微信用户
        RegisterPayOrder payOrder = new RegisterPayOrder();
        payOrder.setDoctorId(doctorId);
        payOrder.setRelationId(recods.getId());
        payOrder.setStatus(RegisterEnum.OPERATE.getCode());
        payOrder.setWxUserinfoId(wxUserinfo.getId());
        RegisterPayOrder registerPayOrder = registerPayOrderService.getByRelationId(payOrder);

        //生成退款申请记录
        RegisterRefoundAudit registerRefoundAudit = new RegisterRefoundAudit();
        registerRefoundAudit.setOpenid(recods.getOpenid());
        registerRefoundAudit.setRegisterPayOrderId(registerPayOrder.getId());
        registerRefoundAudit.setStatus(0);
//        registerRefoundAudit.setDoctorId(doctorRegister.getDoctorId());
        registerRefoundAudit.setRelationId(recods.getId());


        //获取医生信息
//        Doctor doctorInfo = doctorService.getById(doctorRegister.getDoctorId());
//        registerRefoundAudit.setDoctorName(doctorInfo.getName());

        //患者信息
        registerRefoundAudit.setRequestTime(new Date());
        registerRefoundAudit.setNickName(wxUserinfo.getNickname());


        String patientId = doctorRegisterRecordService.getById(recods.getId()).getPatientId();
        RegisterPatient patientInfo = registerPatientService.getById(patientId);
        registerRefoundAudit.setMobile(patientInfo.getMobile());
        registerRefoundAudit.setPatientName(patientInfo.getName());
        registerRefoundAudit.setIdCard(patientInfo.getIdCard());
        registerRefoundAudit.setXsResion(xsResion);
        registerRefoundAuditService.save(registerRefoundAudit);

        return Result.ok("退款申请成功！");
    }

}
